package net.shopxx.action.shop;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.jsp.PageContext;

import net.shopxx.bean.TenpayConfig;
import net.shopxx.bean.TenpayConfig.TenpayType;
import net.shopxx.common.CommentUtil;
import net.shopxx.entity.Order;
import net.shopxx.entity.OrderItem;
import net.shopxx.entity.OrderLog;
import net.shopxx.entity.Payment;
import net.shopxx.entity.PaymentConfig;
import net.shopxx.entity.Product;
import net.shopxx.entity.Order.OrderStatus;
import net.shopxx.entity.Order.ShippingStatus;
import net.shopxx.entity.OrderLog.OrderLogType;
import net.shopxx.entity.Payment.PaymentStatus;
import net.shopxx.entity.Payment.PaymentType;
import net.shopxx.entity.PaymentConfig.PaymentConfigType;
import net.shopxx.service.HtmlService;
import net.shopxx.service.OrderLogService;
import net.shopxx.service.OrderService;
import net.shopxx.service.PayService;
import net.shopxx.service.PaymentConfigService;
import net.shopxx.service.PaymentService;
import net.shopxx.service.ProductService;
import net.shopxx.service.impl.HuiPayServiceImpl;
import net.shopxx.util.ArithUtil;
import net.shopxx.util.PayUtil;
import net.shopxx.util.SystemConfigUtil;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.ParentPackage;

import sun.misc.BASE64Decoder;
import chinapnr.SecureLink;

import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.web.ServletCacheAdministrator;
import com.opensymphony.xwork2.interceptor.annotations.InputConfig;
import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;

/**
 * 前台Action类 - 支付处理
 */

@ParentPackage("member")
@InterceptorRefs( {
		@InterceptorRef(value = "token", params = { "excludeMethods",
				"confirm,tenpayReturn" }),
		@InterceptorRef(value = "memberStack") })
public class PaymentAction extends BaseShopAction {

	private static final long serialVersionUID = -4817743897444468581L;

	// 支付结果（成功、失败）
	public enum PaymentResult {
		success, failure
	}

	private PaymentType paymentType;// 支付类型
	private BigDecimal amountPayable;// 应付金额（不含支付费用）
	private BigDecimal paymentFee;// 支付手续费
	private PaymentResult paymentResult;// 支付结果
	private PaymentConfig paymentConfig;// 支付方式
	private Order order;// 订单

	private String payUrl = "http://mas.chinapnr.com/gar/RecvMerchant.do";
	private String refundUrl = "http://mas.chinapnr.com/gao/entry.do";
	private String version = "10";
	private String cmdId = "Buy";
	private String merId = "870708";
	private String ordId = "";
	private String oldOrdId = "";
	private String ordAmt = "";
	private String curCode = "RMB";
	private String pid = "";
	private String retUrl = SystemConfigUtil.getSystemConfig().getShopUrl()+"xysc/pay/huifu!paynotify.action";
	private String bgRetUrl = SystemConfigUtil.getSystemConfig().getShopUrl()+"xysc/pay/huifu!payret.action";
	private String refundRetUrl = SystemConfigUtil.getSystemConfig().getShopUrl()+"xysc/pay/huifu!refund.action";
	private String merPriv = "";
	private String gateId = "";
	private String usrMp = "";
	private String divDetails = "";
	private String payUsrId = "";
	private String chkValue = "";

	@Resource
	private PaymentConfigService paymentConfigService;
	@Resource
	private PaymentService paymentService;
	@Resource
	private OrderService orderService;
	@Resource
	private OrderLogService orderLogService;
	@Resource
	private ProductService productService;
	@Resource
	private HtmlService htmlService;
	
	private PayService huiPayService= new HuiPayServiceImpl();

	// 支付确认
	@Validations(requiredFields = { @RequiredFieldValidator(fieldName = "paymentType", message = "参数错误！") })
	@InputConfig(resultName = "error")
	public String confirm() {
		if (order == null || StringUtils.isEmpty(order.getId())) {
			addActionError("订单信息错误！");
			return ERROR;
		}
		order = orderService.load(order.getId());
		paymentConfig = order.getPaymentConfig();
		paymentFee = order.getPaymentFee();
		amountPayable = order.getTotalAmount().subtract(paymentFee).subtract(
				order.getPaidAmount());

		for (OrderItem item : order.getOrderItemSet()) {
			pid = item.getProductSn();
			break;
		}
		ordId= order.getOrderSn();
		ordAmt = ArithUtil.getDecimals(order.getTotalAmount());
		divDetails = order.getDivDetails();
//		String MerKeyFile = CommentUtil.class.getClassLoader().getResource("").getPath()+PayUtil.PRIVATE_KEY; 
		String MerData = version + cmdId + merId + ordId + ordAmt + curCode
				+ pid + retUrl + merPriv + gateId + usrMp + divDetails
				+ payUsrId + bgRetUrl;
		try {
			chkValue = huiPayService.sign(MerData);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		
//		SecureLink secureLink = new SecureLink();
//		int ret = secureLink.SignMsg(PayUtil.MER_ID,MerKeyFile, MerData);
//		if (ret != 0) {
//			addActionError("签名错误 ret=！" + ret);
//			return ERROR;
//		}
//		chkValue = secureLink.getChkValue();
		setResponseNoCache();
		return "confirm";
	}
	
	//退款确认
	@InputConfig(resultName = "error")
	public String refund() {
		if (order == null || StringUtils.isEmpty(order.getId())) {
			addActionError("订单信息错误！");
			return ERROR;
		}
		order = orderService.load(order.getId());
		paymentConfig = order.getPaymentConfig();
		paymentFee = order.getPaymentFee();
		amountPayable = order.getTotalAmount().subtract(paymentFee).subtract(
				order.getPaidAmount());
		ordId= order.getOrderSn();
		oldOrdId= order.getOrderSn();
		ordAmt = ArithUtil.getDecimals(order.getTotalAmount());
		divDetails = order.getDivDetails();
		cmdId = "Refund";
		String	MerData = version + cmdId + merId   + ordAmt + ordId + oldOrdId + refundRetUrl;	
		
//		String MerKeyFile = CommentUtil.class.getClassLoader().getResource("").getPath()+privateKey; 
//		SecureLink secureLink = new SecureLink();
//		int ret = secureLink.SignMsg(merId, MerKeyFile, MerData);
//		if (ret != 0) {
//			addActionError("签名错误 ret=！" + ret);
//			return ERROR;
//		}
//		chkValue = secureLink.getChkValue();
		
		try {
			chkValue = huiPayService.sign(MerData);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		
		StringBuffer sb = new StringBuffer();
		sb.append("ChkValue="+chkValue);
		sb.append("&Version="+version);
		sb.append("&CmdId="+cmdId);
		sb.append("&MerId="+merId);
//		sb.append("&DivDetails="+divDetails);
		sb.append("&RefAmt="+ordAmt);
		sb.append("&OrdId="+ordId);
		sb.append("&OldOrdId="+oldOrdId);
		sb.append("&BgRetUrl="+refundRetUrl);
		try {
			String resp = PayUtil.getNetConn(refundUrl, sb.toString());
			if(resp.contains("RespCode=000000"))
			{
				if (order == null) {
					System.out.println("no order");
					return "error";
				}
				// 库存处理
				if (order.getPaymentStatus() == Order.PaymentStatus.paid
						&& order.getShippingStatus() == ShippingStatus.unshipped) {
					for (OrderItem orderItem : order.getOrderItemSet()) {
						Product product = orderItem.getProductitem()
						.getProduct();
						if (product.getStore() != null) {
							product.setFreezeStore(product.getFreezeStore()
									- orderItem.getProductQuantity());
							productService.update(product);
							if (product.getIsOutOfStock()) {
								flushCache();
								htmlService
								.productContentBuildHtml(product);
							}
						}
					}
				}
				order.setPaymentStatus(Order.PaymentStatus.refunded);
				orderService.update(order);
				
				// 订单日志
				OrderLog orderLog = new OrderLog();
				orderLog.setOrderLogType(OrderLogType.payment);
				orderLog.setOrderSn(order.getOrderSn());
				orderLog.setOperator("");
				orderLog.setInfo("退款["+order.getTotalAmount()+"]成功");
				orderLog.setOrder(order);
				orderLogService.save(orderLog);
			}
			else
			{
				addActionError("退款失败");
				return ERROR;
			}
		} catch (Exception e) {
			addActionError("网络错误");
			return ERROR;
		}
		setResponseNoCache();
		return "refund";
	}

	// 更新页面缓存
	private void flushCache() {
		Cache cache = ServletCacheAdministrator.getInstance(
				getRequest().getSession().getServletContext()).getCache(
				getRequest(), PageContext.APPLICATION_SCOPE);
		cache.flushAll(new Date());
	}

	public PaymentType getPaymentType() {
		return paymentType;
	}

	public void setPaymentType(PaymentType paymentType) {
		this.paymentType = paymentType;
	}

	public BigDecimal getAmountPayable() {
		return amountPayable;
	}

	public void setAmountPayable(BigDecimal amountPayable) {
		this.amountPayable = amountPayable;
	}

	public BigDecimal getPaymentFee() {
		return paymentFee;
	}

	public void setPaymentFee(BigDecimal paymentFee) {
		this.paymentFee = paymentFee;
	}

	public PaymentResult getPaymentResult() {
		return paymentResult;
	}

	public void setPaymentResult(PaymentResult paymentResult) {
		this.paymentResult = paymentResult;
	}

	public PaymentConfig getPaymentConfig() {
		return paymentConfig;
	}

	public void setPaymentConfig(PaymentConfig paymentConfig) {
		this.paymentConfig = paymentConfig;
	}

	public Order getOrder() {
		return order;
	}

	public void setOrder(Order order) {
		this.order = order;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getCmdId() {
		return cmdId;
	}

	public void setCmdId(String cmdId) {
		this.cmdId = cmdId;
	}

	public String getMerId() {
		return merId;
	}

	public void setMerId(String merId) {
		this.merId = merId;
	}

	public String getOrdId() {
		return ordId;
	}

	public void setOrdId(String ordId) {
		this.ordId = ordId;
	}

	public String getOrdAmt() {
		return ordAmt;
	}

	public void setOrdAmt(String ordAmt) {
		this.ordAmt = ordAmt;
	}

	public String getCurCode() {
		return curCode;
	}

	public void setCurCode(String curCode) {
		this.curCode = curCode;
	}

	public String getPid() {
		return pid;
	}

	public void setPid(String pid) {
		this.pid = pid;
	}

	public String getRetUrl() {
		return retUrl;
	}

	public void setRetUrl(String retUrl) {
		this.retUrl = retUrl;
	}

	public String getBgRetUrl() {
		return bgRetUrl;
	}

	public void setBgRetUrl(String bgRetUrl) {
		this.bgRetUrl = bgRetUrl;
	}

	public String getMerPriv() {
		return merPriv;
	}

	public void setMerPriv(String merPriv) {
		this.merPriv = merPriv;
	}

	public String getGateId() {
		return gateId;
	}

	public void setGateId(String gateId) {
		this.gateId = gateId;
	}

	public String getUsrMp() {
		return usrMp;
	}

	public void setUsrMp(String usrMp) {
		this.usrMp = usrMp;
	}

	public String getDivDetails() {
		return divDetails;
	}

	public void setDivDetails(String divDetails) {
		this.divDetails = divDetails;
	}

	public String getPayUsrId() {
		return payUsrId;
	}

	public void setPayUsrId(String payUsrId) {
		this.payUsrId = payUsrId;
	}

	public String getPayUrl() {
		return payUrl;
	}

	public void setPayUrl(String payUrl) {
		this.payUrl = payUrl;
	}

	public String getChkValue() {
		return chkValue;
	}

	public void setChkValue(String chkValue) {
		this.chkValue = chkValue;
	}

	public String getRefundUrl() {
		return refundUrl;
	}

	public void setRefundUrl(String refundUrl) {
		this.refundUrl = refundUrl;
	}

	public String getOldOrdId() {
		return oldOrdId;
	}

	public void setOldOrdId(String oldOrdId) {
		this.oldOrdId = oldOrdId;
	}

	public String getRefundRetUrl() {
		return refundRetUrl;
	}

	public void setRefundRetUrl(String refundRetUrl) {
		this.refundRetUrl = refundRetUrl;
	}
	
	

}